package team.seekers.oj.course.service;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import team.seekers.oj.common.enums.ApiExceptionEnum;
import team.seekers.oj.common.util.AssertUtils;
import team.seekers.oj.common.util.RedisUtils;
import team.seekers.oj.course.dao.CourseDao;
import team.seekers.oj.course.dao.CourseLiveDao;
import team.seekers.oj.course.entity.CourseDO;
import team.seekers.oj.course.entity.CourseLiveDO;
import team.seekers.oj.course.entity.vo.CourseLiveInfoVO;
import team.seekers.oj.course.entity.vo.CourseLiveRecordInfoVO;
import team.seekers.oj.course.entity.vo.CourseLiveRecordListVO;
import team.seekers.oj.course.enums.CourseStatusEnum;
import team.seekers.oj.third.controller.EtherpadController;
import team.seekers.oj.third.controller.LiveController;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

@Service
public class CourseLiveService {

    @Autowired
    private LiveController liveController;

    @Autowired
    private EtherpadController etherpadController;

    @Autowired
    private CourseLiveDao courseLiveDao;

    @Autowired
    private CourseDao courseDao;

    @Autowired
    private RedisUtils redisUtils;

    @Transactional(rollbackFor = Exception.class)
    public String startLive(Long courseId, String title) {
        String pushUrl = liveController.createPushUrl(courseId.toString());
        String pullUrl = liveController.createPlayUrl("m3u8", courseId.toString());

        CourseLiveDO courseLiveDO = new CourseLiveDO();
        courseLiveDO.setTitle(title);
        courseLiveDO.setCourseId(courseId);
        courseLiveDO.setStatus(1);
        courseLiveDO.setPushAddress(pushUrl);
        courseLiveDO.setPullAddress(pullUrl);

        courseLiveDao.save(courseLiveDO);

        // 创建协同白板
        etherpadController.create(courseLiveDO.getId().toString());

        // 修改课程状态
        CourseDO courseDO = new CourseDO();
        courseDO.setId(courseId);
        courseDO.setStatus(CourseStatusEnum.TEACHING.getType());
        courseDao.updateById(courseDO);

        return pushUrl;
    }

    @Transactional(rollbackFor = Exception.class)
    public void endLive(Long courseId) {
        CourseLiveDO courseLiveDO = courseLiveDao.lambdaQuery()
                .eq(CourseLiveDO::getCourseId, courseId)
                .eq(CourseLiveDO::getStatus, 1).one();
        AssertUtils.notNull(courseLiveDO ,
                ApiExceptionEnum.COURSE_LIVE_NOT_FOUND);

        CourseLiveDO courseLiveDO1 = new CourseLiveDO();
        courseLiveDO1.setId(courseLiveDO.getId());
        courseLiveDO1.setStatus(2);
        courseLiveDao.updateById(courseLiveDO1);

        // 删除redis中缓存的数据
        redisUtils.del(courseLiveDO.getId()+"-watch",courseLiveDO.getId()+"-code");

        // 修改课程状态
        CourseDO courseDO = new CourseDO();
        courseDO.setId(courseId);
        courseDO.setStatus(CourseStatusEnum.OPEN.getType());
        courseDao.updateById(courseDO);
    }

    public CourseLiveInfoVO liveInfo(Long courseId) {
        CourseLiveDO courseLiveDO = courseLiveDao.lambdaQuery()
                .eq(CourseLiveDO::getCourseId, courseId).eq(CourseLiveDO::getStatus, 1).one();
        AssertUtils.notNull(courseLiveDO,
                ApiExceptionEnum.COURSE_NOT_FOUND, "直播不存在");
        CourseLiveInfoVO courseLiveInfoVO = new CourseLiveInfoVO();
        BeanUtils.copyProperties(courseLiveDO,courseLiveInfoVO);
        return courseLiveInfoVO;
    }

    public List<CourseLiveRecordListVO> liveRecords(Long courseId) {
        List<CourseLiveDO> courseLiveDOList = courseLiveDao.lambdaQuery()
                .eq(CourseLiveDO::getCourseId, courseId)
                .orderByAsc(CourseLiveDO::getGmtCreate).list();
        ArrayList<CourseLiveRecordListVO> courseLiveListVOS = new ArrayList<>();
        for (CourseLiveDO courseLiveDO : courseLiveDOList) {
            CourseLiveRecordListVO courseLiveListVO = new CourseLiveRecordListVO();
            BeanUtils.copyProperties(courseLiveDO,courseLiveListVO);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            courseLiveListVO.setStartTime(simpleDateFormat.format(courseLiveDO.getGmtCreate()));
            courseLiveListVOS.add(courseLiveListVO);
        }
        return courseLiveListVOS;
    }

    public CourseLiveRecordInfoVO getRecordInfoById(Long liveRecordId) {
        CourseLiveDO one = courseLiveDao.lambdaQuery()
                .eq(CourseLiveDO::getId, liveRecordId).one();
        CourseLiveRecordInfoVO courseLiveRecordInfoVO = new CourseLiveRecordInfoVO();
        BeanUtils.copyProperties(one,courseLiveRecordInfoVO);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        courseLiveRecordInfoVO.setStartTime(simpleDateFormat.format(one.getGmtCreate()));
        return courseLiveRecordInfoVO;
    }
}
